package cn.zhxu.toys.concurrent;

/**
 * 简单的雪花 ID（非常规雪花）生成器
 *  | 1 bits | 41 bits | 10 bits | 12 bits |
 *    符号位0    时间戳    机器码     序列号
 */
public class SnowIdGenerator {

    // 以 2025-01-01 00:00.000 为基线时间（单位：毫秒）
    private final static long BASE_TIMESTAMP = 28927680L * 60000;

    private final long machineId;

    private final int machineBits;
    private final int serialBits;
    private final int timeRSBits;   // 时机戳右移位数

    private volatile long sequence = 0;

    public SnowIdGenerator(long machineId) {
        this(machineId, 10, 12, 0);
    }

    public SnowIdGenerator(long machineId, int timeRSBits) {
        this(machineId, 10, 12, timeRSBits);
    }

    public SnowIdGenerator(long machineId, int machineBits, int serialBits, int timeRSBits) {
        this.machineId = machineId;
        this.machineBits = machineBits;
        this.serialBits = serialBits;
        this.timeRSBits = timeRSBits;
    }

    public synchronized long nextId() {
        long timestamp = (System.currentTimeMillis() - BASE_TIMESTAMP) >> timeRSBits;
        if (++sequence >= (1L << (serialBits))) {
            sequence = 0;
        }
        return (timestamp << (machineBits + serialBits)) | (machineId << serialBits) | sequence;
    }

}
